# -*- coding: utf-8 -*-
import os
import sys
from time import sleep
import arrow
from fabric.api import sudo, env, run, local
from fabric.contrib.files import append
from fabric.contrib.project import rsync_project
from fabric.colors import red, green, cyan, blue, yellow
from config.stage import STAGES


def print_error(msg, stop=True):
    print(red(u" ✘   %s\n\n ✘   Task failed. Fix issues list above.\n" % msg))
    if stop:
        sys.exit()


def print_warning(msg):
    print(yellow(" !   %s ..." % msg))


def print_start(msg):
    print(cyan("==>> %s ..." % msg))


def print_done(msg):
    print(green(u" ✔   %s" % msg))


def print_info(msg):
    print(blue(u" ☞   %s" % msg))


PROJECT_DIRS = {
    'maestro': '../',
}

SETTING_FILES_PATH = {
    'maestro': '',
}

if "stage" not in env:
    print(red(u" ✘   Stage not set, use `--set stage=<STAGE>`.\n"))
    sys.exit()

if env.stage not in STAGES:
    print(red(u" ✘   Stage invalid, check `config.py`.\n"))
    sys.exit()

env.roledefs = STAGES[env.stage]["roledefs"]
env.setting_file_path = SETTING_FILES_PATH
env.user = STAGES[env.stage]["user"]
env.key_filename = STAGES[env.stage]["key_filename"]

_CONFIG_FILE_PATH = os.path.dirname(os.path.abspath(__file__)) + '/config_files/'
_CWD = os.getcwd()

_ROLE = env.roles[0]
_REMOTE_PROJECT_DIR = "/opt/%s" % _ROLE
_AVAILABLE_DIR = "%s/available/" % _REMOTE_PROJECT_DIR
_ENABLED_DIR = "%s/enabled/" % _REMOTE_PROJECT_DIR
_ENABLED_APP_DIR = "%s/enabled/app" % _REMOTE_PROJECT_DIR
_SETTING_DIR = "%s/enabled/app/%s/" % (_REMOTE_PROJECT_DIR, env.setting_file_path.get(_ROLE))
_LOG_DIR = "/var/log/%s" % _ROLE

_SOURCE_CODE_DIR = PROJECT_DIRS.get(_ROLE)


def check_variables():
    print_info("project dir: %s" % PROJECT_DIRS.get(_ROLE))


def setup_server():
    print_start("Setting up server")
    sudo("apt-get install -y zsh curl git libgeoip1 libgeoip-dev geoip-bin")
    sudo("mkdir -p %s" % _AVAILABLE_DIR)
    sudo("mkdir -p %s" % _ENABLED_DIR)
    sudo("mkdir -p %s" % _LOG_DIR)
    sudo("mkdir -p /var/log/agent")
    sudo("chown maestro:maestro -R %s" % _REMOTE_PROJECT_DIR)
    sudo("chown maestro:maestro -R %s" % _LOG_DIR)
    sudo("sysctl -w net.core.somaxconn=4096")
    append("/etc/sysctl.conf", "net.core.somaxconn=4096", use_sudo=True)
    print_done("Setting up server done.")


def upload_src():
    print_start("Uploading source code")
    now_str = arrow.now().format("YYYYMMDDHHmmss")
    available_app_dir = "%s/available/app_%s/" % (_REMOTE_PROJECT_DIR, now_str)
    run("mkdir -p %s" % available_app_dir)
    rsync_project(available_app_dir, "%s/" % _SOURCE_CODE_DIR,
                  exclude=['.git', '*.tar.bz2', '.idea', '*.deb', '.gitignore', '.python-version', '*.pyc'],
                  extra_opts="--filter='dir-merge,- .gitignore'")
    run("rm -fr %s" % _ENABLED_APP_DIR)
    run("ln -s %s %s" % (available_app_dir, _ENABLED_APP_DIR))
    if _ROLE in SETTING_FILES_PATH:
        run("mv /opt/maestro/enabled/app/webservices/settings_%s.py "
            "/opt/maestro/enabled/app/webservices/env_settings.py"
            % env.stage)
    print_done("Installing requirements done.")


def restart_service():
    print_start("restarting %s" % _ROLE)
    if 'maestro' == _ROLE and env.host == '3.1.126.5':
        sudo("supervisorctl update")
        sudo("supervisorctl stop maestro:maestro-uwsgi")
        sleep(5)
        sudo("chown maestro:maestro -R %s" % _LOG_DIR)
        sudo("supervisorctl start maestro:maestro-uwsgi")
    print_done("restarting %s done." % _ROLE)


def repository_pre_process():
    print_start("Checking git repo")
    result = local("git status --porcelain", capture=True)
    if result.stdout:
        print_error("Git repo is dirty, commit your change first!")
    remote_url = local("git remote get-url --all maestro", capture=True)
    print(remote_url)
    if not remote_url.stdout:
        local("git remote add maestro git@52.220.212.168:maestro/data-analysis.git")
    local("git checkout master")
    local("git pull --no-edit maestro master")
    print_done("Checking git repo done.")


def deploy():
    # repository_pre_process()
    # setup_server()
    upload_src()
    restart_service()
    print_done("Deploy done.\n")
